﻿using System;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;

namespace CSLauncher.Hotkey.Interface
{
    [Serializable]
    [TypeConverter(typeof(HotkeyDataTypeConverter))]
    internal struct HotkeyData
    {
        public bool Alt { get; private set; }
        public bool Shift { get; private set; }
        public bool Ctrl { get; private set; }
        public bool Winkey { get; private set; }
        public Keys Key { get; private set; }

        public HotkeyData(bool alt, bool shift, bool ctrl, bool winkey, Keys key) : this()
        {
            Alt = alt;
            Shift = shift;
            Ctrl = ctrl;
            Winkey = winkey;
            Key = key;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            if (Alt)
            {
                sb.Append("Alt + ");
            }

            if (Ctrl)
            {
                sb.Append("Ctrl + ");
            }

            if (Shift)
            {
                sb.Append("Shift + ");
            }

            if (Winkey)
            {
                sb.Append("Winkey + ");
            }

            sb.Append(Key);
            return sb.ToString();
        }

        public void CopyTo(ref HotkeyData dest)
        {
            dest.Alt = Alt;
            dest.Ctrl = Ctrl;
            dest.Shift = Shift;
            dest.Winkey = Winkey;
            dest.Key = Key;
        }
    }

    internal class HotkeyDataTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }

            return base.CanConvertFrom(context, sourceType);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                return true;
            }

            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType != typeof(string))
            {
                return base.ConvertTo(context, culture, value, destinationType);
            }
            
            StringBuilder sb = new StringBuilder();
            HotkeyData data = (HotkeyData)value;

            if (data.Alt)
            {
                sb.Append("Alt,");
            }

            if (data.Ctrl)
            {
                sb.Append("Ctrl,");
            }

            if (data.Shift)
            {
                sb.Append("Shift,");
            }

            if (data.Winkey)
            {
                sb.Append("Winkey,");
            }

            sb.Append(data.Key);

            return sb.ToString();
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (!(value is string))
            {
                return base.ConvertFrom(context, culture, value);
            }

            string serialized = (string)value;
            string[] data = serialized.Split(',');
            
            bool alt = false;
            bool ctrl = false;
            bool winkey = false;
            bool shift = false;

            for (int i = 0; i < data.Length - 1; ++i)
            {
                string key = data[i];

                switch (key)
                {
                    case "Alt":
                        alt = true;
                        break;

                    case "Ctrl":
                        ctrl = true;
                        break;

                    case "Winkey":
                        winkey = true;
                        break;

                    case "Shift":
                        shift = true;
                        break;
                }
            }

            return new HotkeyData(alt, shift, ctrl, winkey, (Keys)Enum.Parse(typeof (Keys), data[data.Length - 1]));
        }
    }
}
